home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / progjrn / pj_7_6.arc / WINDEV.ARC / WNTINT.C < prev    next >
C/C++ Source or Header  |  1989-07-30  |  11KB  |  337 lines

  1. /*
  2.  * WNTERM initialization module
  3.  *
  4.  * Written by
  5.  * William S. Hall
  6.  * 3665 Benton Street, #66
  7.  * Santa Clara, CA 95051
  8. */
  9.  
  10. #define NOMINMAX
  11. #define NOATOM
  12. #define NOKANJI
  13. #define NOSOUND
  14. #include <windows.h>
  15. #include <limits.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18. #include <ascii.h>
  19. #include "ttycls.h"
  20. #include "wnterm.h"
  21.  
  22. /* local function declarations */
  23. static BOOL NEAR RegisterMainWindowClass(HANDLE);
  24. static void NEAR GetPrevInstanceData(HANDLE);
  25. static BOOL NEAR MakeAndShowMainWnd(HANDLE, int);
  26. static BOOL NEAR OpenAndSetCommPort(HANDLE);
  27. static BOOL NEAR SearchKey(char *str, char *key, int len);
  28. short FAR PASCAL FindSmallFont(LPLOGFONT, LPTEXTMETRIC, short, LPSTR);
  29.  
  30. /* this function calls all initialization routines */
  31. BOOL FAR InitProgram(hInstance,hPrevInstance, lpszCmdLine, cmdShow)
  32. HANDLE hInstance, hPrevInstance;
  33. LPSTR lpszCmdLine;
  34. int cmdShow;
  35. {
  36.  
  37.     hInst = hInstance;        // need this value in various places
  38.  
  39.   // if first instance, register windows and get string for icon.
  40.   // otherwise, just load data normally obtained during registration.
  41.     if (!hPrevInstance) {
  42.         LoadString(hInstance,IDS_ICONSTRING,(LPSTR)szIconTitle,
  43.             sizeof(szIconTitle));
  44.     if (!RegisterMainWindowClass(hInstance))
  45.         return FALSE;
  46.     }
  47.     else
  48.     GetPrevInstanceData(hPrevInstance);
  49.  
  50.   // now create and show the main window.
  51.     if (!MakeAndShowMainWnd(hInstance,cmdShow))
  52.     return FALSE;
  53.  
  54.   // open the communications port.
  55.     if (!OpenAndSetCommPort(hInstance))
  56.     return FALSE;
  57.  
  58.   // Activate the local/line menu selection to put the terminal on line
  59.     SendMessage(MWnd.hWnd, WM_COMMAND, IDM_OFFLINE,0L);
  60.  
  61.   // indicate successful initialization.
  62.     return TRUE;
  63. }
  64.  
  65. /* register the main window */
  66. static BOOL NEAR RegisterMainWindowClass(HANDLE hInstance)
  67. {
  68.  
  69.     WNDCLASS WndClass;
  70.  
  71.   // get the class name from the resource segment.
  72.     LoadString(hInstance,IDS_APPNAME,(LPSTR)szAppName,sizeof(szAppName));
  73.  
  74.   // clear the WndClass data area
  75.     memset(&WndClass,0, sizeof(WndClass));
  76.  
  77.   // fill in the data.
  78.     WndClass.hCursor    = LoadCursor(NULL, IDC_ARROW);
  79.     WndClass.hIcon    = NULL;            // no icon bitmap.
  80.     WndClass.lpszMenuName = (LPSTR)szAppName;    // use this menu.
  81.     WndClass.lpszClassName = (LPSTR)szAppName;    // this class
  82.     WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // let Windows do it
  83.     WndClass.hInstance = hInstance;        // this instance
  84.     WndClass.style = CS_VREDRAW | CS_HREDRAW;    // basic style
  85.     WndClass.lpfnWndProc = MainWndProc;        // window proc
  86.     WndClass.cbWndExtra = sizeof(PTTYWND);    // data associated with window
  87.     if (!RegisterClass((LPWNDCLASS)&WndClass))
  88.     return FALSE;
  89.  
  90.   // show success.
  91.     return TRUE;
  92.  
  93. }
  94.  
  95. /* if we don't need to register the window, we have to load these strings */
  96. static void NEAR GetPrevInstanceData(HANDLE hPrevInstance)
  97. {
  98.  
  99.     GetInstanceData(hPrevInstance, (PSTR)szAppName, sizeof(szAppName));
  100.     GetInstanceData(hPrevInstance, (PSTR)szIconTitle, sizeof(szIconTitle));
  101. }
  102.  
  103. /* make the main window */
  104. static BOOL NEAR MakeAndShowMainWnd(hInstance, cmdShow)
  105. HANDLE hInstance;
  106. int cmdShow;
  107. {
  108.  
  109.     char szWinTitle[50];
  110.  
  111.   // get the title from the resource segment.
  112.     LoadString(hInstance, IDS_WINTITLE, (LPSTR)szWinTitle,sizeof(szWinTitle));
  113.  
  114.   // create the window.
  115.     MWnd.hWnd = CreateWindow((LPSTR)szAppName,        // class
  116.                  (LPSTR)szWinTitle,        // title
  117.                  WS_OVERLAPPEDWINDOW,    // default type
  118.                  CW_USEDEFAULT,0,        // default position
  119.                  CW_USEDEFAULT,0,        // and size
  120.                  (HWND)NULL,        // no parent
  121.                  (HMENU)NULL,        // class menu
  122.                  (HANDLE)hInstance,        // instance
  123.                  (LPSTR)&MWnd);        // extra create data
  124.  
  125.   // continue if window created and text buffer initialized.
  126.     if (MWnd.hWnd && MWnd.hVidBuf) {
  127.     ShowWindow(MWnd.hWnd, cmdShow);        // show window
  128.         UpdateWindow(MWnd.hWnd);        // paint it
  129.     return TRUE;                // show success
  130.     }
  131.     return FALSE;                // show failure
  132. }
  133.  
  134. static LOGFONT *pttyfat; // used to find a small font if requested in win.ini
  135.  
  136. /* 
  137.  * this function is called by Windows until all fonts of the specified
  138.  * type have been enumerated.
  139.  */
  140. short FAR PASCAL FindSmallFont(lpLF, lpTM, type, lpData)
  141. LPLOGFONT lpLF;
  142. LPTEXTMETRIC lpTM;
  143. short type;
  144. LPSTR lpData;
  145. {
  146.  
  147.     register int i;
  148.     static short refheight = 0;
  149.     short refwidth = LOWORD(lpData);
  150.     short height = lpTM->tmHeight + lpTM->tmExternalLeading;
  151.     short width = lpTM->tmAveCharWidth;
  152.  
  153.   // lpData contains the width and height of the system font, which is used
  154.   // as a reference value.  On the first pass, it must be initialized.
  155.     if (refheight == 0)
  156.     refheight = HIWORD(lpData);
  157.  
  158.   // if we find a smaller font, get its paramters.
  159.     if ((height < refheight) && (width <= refwidth)) {
  160.     refheight = height;
  161.     pttyfat->lfHeight = lpLF->lfHeight;
  162.     pttyfat->lfWidth = lpLF->lfWidth;
  163.     pttyfat->lfWeight = lpLF->lfWeight;
  164.     pttyfat->lfCharSet = lpLF->lfCharSet;
  165.     pttyfat->lfOutPrecision = lpLF->lfOutPrecision;
  166.     pttyfat->lfClipPrecision = lpLF->lfClipPrecision;
  167.     pttyfat->lfQuality = lpLF->lfQuality;
  168.     pttyfat->lfPitchAndFamily = lpLF->lfPitchAndFamily;
  169.     for (i = 0; i < LF_FACESIZE; i++)
  170.         pttyfat->lfFaceName[i] = lpLF->lfFaceName[i];
  171.     }
  172.     return refheight;
  173. }
  174.  
  175. /* called when main window created */
  176. void WndCreate(HWND hWnd, LPCREATESTRUCT pCS)
  177. {
  178.  
  179.     short width, height, cwidth, cheight;
  180.     TEXTMETRIC TM;
  181.     HDC hDC;
  182.     PTTYWND pMWnd;
  183.     FARPROC fp;
  184.     short result;
  185.     HFONT hfont = NULL;
  186.     BOOL smallfont = FALSE;
  187.     char valstr[80], keystr[20], defstr[20];
  188.     int initlen;
  189.  
  190.   // If the communications port is open, cid >= 0.  If we see that cid 
  191.   // is a large negative number, then we know the comm port is not open.
  192.     cid = INT_MIN;
  193.  
  194.   // get off/on-line menu strings for later use.
  195.     LoadString(hInst, IDS_OFFLINE, (LPSTR)szOffLine,sizeof(szOffLine));
  196.     LoadString(hInst, IDS_ONLINE, (LPSTR)szOnLine,sizeof(szOnLine));
  197.  
  198.   // Create a farproc to the main window procedure.
  199.     fpMainWndProc = MakeProcInstance((FARPROC)MainWndProc, hInst);
  200.  
  201.   // we are going to create a buffer for a window this large.
  202.     width = GetSystemMetrics(SM_CXFULLSCREEN);
  203.     height = GetSystemMetrics(SM_CYFULLSCREEN) - GetSystemMetrics(SM_CYMENU);
  204.  
  205.   // Read win.ini to see if the small font should be used.
  206.   // If there is no win.ini entry, make one first.
  207.     initlen = GetProfileString(szAppName, NULL, "", valstr, sizeof(valstr));
  208.     itoa(smallfont, defstr, 10);    
  209.     LoadString(hInst,IDS_SMALLFONT,(LPSTR)keystr,sizeof(keystr));
  210.     if (!SearchKey(valstr, keystr, initlen))
  211.         WriteProfileString(szAppName, keystr, defstr);
  212.     smallfont = GetProfileInt(szAppName, keystr, smallfont);
  213.  
  214.   // get the system font size
  215.     hDC = GetDC(hWnd);
  216.     GetTextMetrics(hDC, &TM);
  217.     cwidth = TM.tmAveCharWidth;
  218.     cheight = TM.tmHeight + TM.tmExternalLeading;
  219.  
  220.   // If the small font is requested, enumerate all fonts
  221.   //  and pick the one with fixed pitch and the smallest height.
  222.     if (smallfont) {
  223.     pttyfat = (LOGFONT *)LocalAlloc(LPTR, sizeof(LOGFONT));
  224.         LoadString(hInst, IDS_FONTFACE, (LPSTR)valstr, sizeof(valstr));
  225.         fp = MakeProcInstance((FARPROC)FindSmallFont, hInst);
  226.         result = EnumFonts(hDC, valstr, fp, (LPSTR)MAKELONG(cwidth, cheight));
  227.         if ((result > 0) && (cheight - result)) {    // found one
  228.         hfont = CreateFontIndirect(pttyfat);
  229.         if (hfont) {                // get the size
  230.         SelectObject(hDC, hfont);
  231.             GetTextMetrics(hDC, &TM);
  232.             cwidth = TM.tmAveCharWidth;
  233.             cheight = TM.tmHeight + TM.tmExternalLeading;
  234.         }
  235.         }
  236.     FreeProcInstance(fp);
  237.     LocalFree((HANDLE)pttyfat);
  238.     }
  239.     ReleaseDC(hWnd, hDC);
  240.  
  241.   // here we retrieve the pointer to our local window stucture.
  242.     pMWnd = (PTTYWND)LOWORD(pCS->lpCreateParams);
  243.  
  244.   // set the extra data to be the pointer to the TWnd structure.
  245.     SetWindowWord(hWnd,0,(WORD)pMWnd);
  246.  
  247.   // now create the text buffer and set some defaults.
  248.     InitTTYWindow(pMWnd,0,0,width,height,cwidth,cheight,
  249.                 FALSE,FALSE,TRUE,(WORD)hfont,0x7f);
  250. }
  251.  
  252. /* open a communications port */
  253. static BOOL NEAR OpenAndSetCommPort(hInstance)
  254. HANDLE hInstance;
  255. {
  256.  
  257.     char modestr[40];
  258.     char commstr[40];
  259.     char errorstr[80];
  260.     char appstr[10];
  261.     int reply;
  262.  
  263.   // try to open COM1:
  264.     LoadString(hInstance, IDS_FIRSTCOM, (LPSTR)commstr, sizeof(commstr));
  265.     if ((cid = OpenComm((LPSTR)commstr,INQUESIZE,OUTQUESIZE)) < 0) {
  266.      // we failed, so post a message box.
  267.         LoadString(hInstance, IDS_CANNOTOPENFIRSTPORT, (LPSTR)errorstr,
  268.                 sizeof(errorstr));
  269.     reply = MessageBox(MWnd.hWnd, (LPSTR)errorstr, (LPSTR)szAppName,
  270.                 MB_OKCANCEL | MB_ICONQUESTION);
  271.       // if user cancels, quit.
  272.     if (reply == IDCANCEL)
  273.         return FALSE;
  274.       // try to open the next port.
  275.     LoadString(hInstance, IDS_NEXTCOM, (LPSTR)commstr, sizeof(commstr));
  276.     if ((cid = OpenComm((LPSTR)commstr,INQUESIZE,OUTQUESIZE)) < 0) {
  277.       // complete failure, so quit program.
  278.         ShowMessage(MWnd.hWnd, IDS_CANNOTOPENANYPORT);
  279.         return FALSE;
  280.     }
  281.     }
  282.  
  283.   // we opened a port, so we will attach the port name to the title.
  284.     GetWindowText(MWnd.hWnd, (LPSTR)modestr, sizeof(modestr));
  285.     strcat(modestr, commstr);
  286.     SetWindowText(MWnd.hWnd, (LPSTR)modestr);        
  287.  
  288.   // now read in the device control block.
  289.     if (GetCommState(cid, (DCB FAR *)&CommData) >= 0) {
  290.      // read win.ini to find out how to set the port.
  291.     LoadString(hInstance, IDS_PORTSECTION, (LPSTR)appstr, sizeof(appstr));
  292.     GetProfileString((LPSTR)appstr,(LPSTR)commstr,(LPSTR)NULL,
  293.             (LPSTR)modestr,sizeof(modestr));
  294.      // concatenate the comm data to the name of the port.
  295.         strcat(commstr, modestr);
  296.      // build the DCB according to commstr.
  297.         if (BuildCommDCB((LPSTR)commstr, (DCB FAR *)&CommData) >= 0) {
  298.       // modify some additional DCB fields.
  299.         CommData.XonLim = INQUESIZE / 8;    // Low water mark
  300.         CommData.XoffLim = INQUESIZE / 8;    // High water mark
  301.         CommData.fNull = TRUE;        // ignore null data
  302.         CommData.XonChar = XON;        // use ^Q for xon
  303.         CommData.XoffChar = XOFF;        // use ^S for xoff
  304.         CommData.fOutX = TRUE;        // set outbound flow control
  305.         CommData.fInX = TRUE;        // set inbound flow control
  306.       // finally, set the values.
  307.         if (SetCommState ((DCB FAR *)&CommData) >= 0)
  308.             return TRUE;
  309.     }
  310.     }
  311.   // everything failed, close the comm port and quit.
  312.     ShowMessage(MWnd.hWnd, IDS_COMMSETERROR);
  313.     CloseComm(cid);
  314.     return FALSE;
  315. }
  316.  
  317. /* Search the keystring buffer for 'key'. Keystrings are delimited by 0's */
  318. static BOOL NEAR SearchKey(char *str, char *key, int len)
  319. {
  320.  
  321.     register int i;
  322.     register char *startptr;
  323.     startptr = str;
  324.  
  325.     for (i = 0; i < len; i++) {
  326.     if (*str++)
  327.         ;
  328.     else {
  329.         if (strcmp(key, startptr) == 0)
  330.         return(TRUE);
  331.         startptr = str;
  332.     }
  333.     }
  334.     return (FALSE);
  335.  
  336. }
  337.